package com.luoqifei.hbase;


import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HbaseTool2 {
    private static Logger log = LoggerFactory.getLogger(HBaseTool.class);
    private static Configuration hbaseConfig = null;
    private static Connection connection;
    public HbaseTool2(String zkIp, String zkPort)  {
        hbaseConfig = HBaseConfiguration.create();
        hbaseConfig.set("hbase.zookeeper.quorum", zkIp);
        hbaseConfig.set("hbase.zookeeper.property.clientPort", zkPort);
        try {
            connection = ConnectionFactory.createConnection(hbaseConfig);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void close() {
        if (connection != null) {
            if (!connection.isClosed()) {
                try {
                    connection.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * create table
     *
     * @param tableName
     * @param columnFamilies
     * @throws Exception
     */
    private void createTable(String tableName, List<String> columnFamilies) throws Exception {
        log.info("start to create table : {}", tableName);
        Admin hBaseAdmin = connection.getAdmin();
        if (hBaseAdmin.tableExists(TableName.valueOf(tableName))) {
            log.warn("Table {} had exists,we delete it.", tableName);
            hBaseAdmin.disableTable(TableName.valueOf(tableName));
            hBaseAdmin.deleteTable(TableName.valueOf(tableName));
            log.warn("Table {} delete successed.", tableName);
        }
        if (columnFamilies == null || columnFamilies.size() == 0) {
            log.error("the column family is null or size==0.");
            throw new Exception("when add table ,we need special the column family.");
        }
        HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf(tableName));
        for (String cf : columnFamilies) {
            tableDescriptor.addFamily(new HColumnDescriptor(cf));
        }
        hBaseAdmin.createTable(tableDescriptor);
        log.info("success to create table : {} .", tableName);
        hBaseAdmin.close();
    }

    /**
     * drop table
     *
     * @param tableName
     * @return
     */
    private boolean dropTable(String tableName) {
        log.info("start to drop table {} .", tableName);
        try {
            Admin hBaseAdmin = connection.getAdmin();
            hBaseAdmin.disableTable(TableName.valueOf(tableName));
            hBaseAdmin.deleteTable(TableName.valueOf(tableName));
            hBaseAdmin.close();
        } catch (IOException e) {
            log.error("fail to drop table {}", tableName);
            e.printStackTrace();
            return false;
        }
        log.info("success to drop table : {} .", tableName);
        return true;
    }

    /**
     * add column family in table
     */
    private void addColumn(String tableName, String columnName) {
        try {
            Admin hBaseAdmin = connection.getAdmin();
            HColumnDescriptor columnDescriptor = new HColumnDescriptor(columnName);
            //add column family
            hBaseAdmin.addColumn(TableName.valueOf(tableName), columnDescriptor);
            hBaseAdmin.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void insertData(String tableName, String rowKey, String cf, HashMap<String, String> cValue) throws IOException {
        log.info("start to insert row data : table name is {},rowkey is {},column family is {},column and values " +
                "is {}.", tableName, rowKey, cf, cValue.toString());
        Table table = connection.getTable(TableName.valueOf(tableName));
        //add data to rowKey
        Put put = new Put(Bytes.toBytes(rowKey));
        //this data in cf column family,and in c column, the value
        for (String c : cValue.keySet()) {
            put.addColumn(Bytes.toBytes(cf), Bytes.toBytes(c), Bytes.toBytes(cValue.get(c)));
        }
        table.put(put);
        table.close();
        log.info("success to insert data,row key is {}.", rowKey);
    }

    /**
     * add one row data in table
     *
     * @param tableName
     */

    public void showAllRecords(String tableName) {
        log.info("start==============show All Records=============");
        Table table = null;
        try {
            table = connection.getTable(TableName.valueOf(tableName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            Scan scan = new Scan();
            ResultScanner rss = table.getScanner(scan);

            for (Result r : rss) {
                log.info("\n row key: " + new String(r.getRow()));

                for (KeyValue kv : r.raw()) {

                    log.info("family=>" + new String(kv.getFamilyArray(), "utf-8")
                            + "  value=>" + new String(kv.getValueArray(), "utf-8")
                            + "  qualifer=>" + new String(kv.getQualifierArray(), "utf-8")
                            + "  timestamp=>" + kv.getTimestamp());
                }
            }
            rss.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info("end==============show All Records=============");
    }

    public Result getOneRecordByRowKey(String tableName, String rowkey) throws IOException {
        Table table = null;
        try {
            table = connection.getTable(TableName.valueOf(tableName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        Get get = new Get(rowkey.getBytes());
        log.info("start to getOneRecordByRowKey from table " + tableName + " and row : " + rowkey);
        Result r = table.get(get);
        table.close();
        return r;
    }
    public static void main(String args[]) throws IOException {
        HbaseTool2 hbaseTool2 = new HbaseTool2("10.32.35.114","2181");
        hbaseTool2.scanByFilter("simulation_extreme");
    }
    public void scanByFilter(String tableName) throws IOException {
        Table table = connection.getTable(TableName.valueOf(tableName));
        Scan scan = new Scan();
        RowFilter rowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL,
                new BinaryPrefixComparator(Bytes.toBytes("GW154P67T103m4KsBSinoma75_V4k0_Offshore_XHW_test")));
        scan.setFilter(rowFilter);
        ResultScanner scanner = table.getScanner(scan);
        for (Result rr :scanner) {
            for (KeyValue kv : rr.list()) {
                System.out.println("row : "+ new String(kv.getRow()));
                System.out.println("qualifier : "+new String(kv.getQualifier()));
                System.out.println("value : "+new String(kv.getValue()));
            }
        }
    }

    public Result getOneRecordByRowKeyAndQualifier(String tableName, String rowKey, String column, String qualifier) throws IOException {
        log.info("start to get one record by rowKey ,column and qualifier. ");
        Table table = connection.getTable(TableName.valueOf(tableName));
        Get get = new Get(rowKey.getBytes());
        get.addColumn(Bytes.toBytes(column), Bytes.toBytes(qualifier));
        Result r = table.get(get);
        log.info("success to get record by rowKey {},and qualifier {} .", rowKey, qualifier);
        table.close();
        return r;
    }

    public String GetTimeByStamp(String timestamp) {
        long datatime = Long.parseLong(timestamp);
        Date date = new Date(datatime);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");
        String timeresult = format.format(date);
        log.info("Time : " + timeresult);
        return timeresult;

    }

    public String GetStampByTime(String time) {
        String Stamp = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date;
        try {
            date = sdf.parse(time);
            Stamp = date.getTime() + "000";
            log.info(Stamp);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return Stamp;
    }

}

